#pragma
#include <iostream>
#include <sys/select.h>
#include <sys/time.h>
#include "Log.hpp"
#include <poll.h>
#include "Socket.hpp"
using namespace std;

static const uint16_t defaultport = 8080;
const int defaultfd = -1;
static const int fd_num_max = 64;
int non_event=0;
class PollServer
{
public:
    PollServer(uint16_t port = defaultport) : _port(port)
    {
        for(int i=0;i<fd_num_max;i++)
        {
            _event_fd[i].fd=defaultfd;
            _event_fd[i].events=non_event;
            _event_fd[i].revents=non_event;
        }
    }
    bool Init()
    {
        _listensock.Socket();
        _listensock.Bind(_port);
        _listensock.Listen();

        return true;
    }
    void Recver(int fd,int pos)
    {
        char buffer[1024];
        ssize_t n=read(fd,buffer,sizeof(buffer)-1);
        if(n>0)
        {
            buffer[n]=0;
            cout<<"get a message:"<<buffer<<endl;
        }
        else if(n==0)
        {
            lg(Info,"client quit,close fd: %d",fd);
            close(fd);
            _event_fd[pos].fd=defaultfd;
        }
        else {
            lg(Warning,"recv error: fd is:%d",fd);
            close(fd);

            _event_fd[pos].fd=defaultfd;
        }
    }
    void Acceptr()
    {
        string client;
        uint16_t clientport=0;
        int sock=_listensock.Accept(&client,&clientport);
        if(sock<0)  return ;
        lg(Info,"accept success,%s:%d,sock fd:%d",client.c_str(),clientport,sock);
        int pos=1;
        for(;pos<fd_num_max;pos++)
        {
            if(_event_fd[pos].fd!=defaultfd)
                continue;
            else 
            {
                break;
            }

        }
        if(pos==fd_num_max)
        {
            lg(Warning,"server is full,close %d now ",sock);
            close(sock);
        }
        else 
        {
            _event_fd[pos].fd=sock;
        
            _event_fd[pos].events=POLLIN;
            _event_fd[pos].revents=non_event;
            PrintFd();
        }
    }
    void Dispatcher()
    {
        for(int i=0;i<fd_num_max;i++)
        {
            int fd=_event_fd[i].fd;
            if(fd==defaultfd)
                continue;
            
            if(_event_fd[i].revents& POLLIN)
            {
                Acceptr();
            }
            else{
                Recver(fd,i);
            }
        }
    }
   
    void Start()
    {
        _event_fd[0].fd=_listensock.Fd();
        _event_fd[0].events=POLLIN;
        int timeout=3000;//3s
        
        for(;;)
        {
            int n=poll(_event_fd,fd_num_max,timeout);
            switch (n)
            {
            case 0:
                cout << "time out"<< endl;
                break;
            case -1:
                cout << "poll erro" << endl;
            default:
                
                cout << "get a new Link" << endl;
                Dispatcher();
                break;
            }
        }
    }


    void PrintFd()
    {
        cout << "online fd list:";
        for (int i = 0; i < fd_num_max; i++)
        {
            if (_event_fd[i].fd == defaultfd)
                continue;
            cout<< _event_fd[i].fd << " ";
        }
        cout << endl;
    }
    ~PollServer()
    {
    }

private:
    Sock _listensock;
    uint16_t _port;
    struct pollfd _event_fd[fd_num_max];//用户维护的
};